﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UCLibrary.UC
{
    [DefaultEvent("Click")]
    public partial class UCValve : UserControl
    {
        Timer timer = new Timer();
        public UCValve()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            timer.Tick += timer_tick;
            timer.Interval = 100;
        }
        public enum ValveType
        {
            singleChanel,doubleChanel
        }
        private ValveType _valveType = ValveType.singleChanel;
        public ValveType valveType
        {
            get { return _valveType; }
            set { _valveType = value; Refresh(); }
        }
        private bool _reversal = false;
        public bool Reversal
        {
            get { return _reversal; }
            set { _reversal = value; Refresh(); }
        } 
        private Color _pipeColor = Color.Black;
        public Color pipeColor
        {
            get { return _pipeColor; }
            set { _pipeColor = value;Refresh(); }
        }
        public enum direction
        {
            up, down, left, right
        }
        private direction _Position = direction.down;
        public direction Position
        {
            get { return _Position; }
            set { _Position = value; Refresh(); }
        }
        private int move = 0;
        private void timer_tick(object sender, EventArgs e)
        {
            move+=-2*Convert.ToInt16(Reversal)+1;
            Refresh();
        }
        private bool _isON = false;
        private bool _flowOK = false;
        public bool flowOK
        {
            get { return _flowOK; }
            set 
            { 
                _flowOK = value; 
                if (value)
                    timer.Start();
                else
                    timer.Stop();
                Refresh();
            }
        }
        public bool isON
        {
            get { return _isON; }
            set 
            { 
                _isON = value;
                if (value)
                    timer.Start();
                else
                {
                    if(valveType==ValveType.singleChanel)
                    {
                        flowOK = false;
                        timer.Stop();
                    }
                }
                Refresh();
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            Function.setHighQuality( g);
            GraphicsPath switchPath = new GraphicsPath();
            GraphicsPath waterPath = new GraphicsPath();
            Matrix matrix = new Matrix();
            switch(valveType)
            {
                //单通道
                case ValveType.singleChanel:
                    switch (Position)
                    {
                        case direction.up:
                            matrix.RotateAt(-45, new Point(Width / 2, Height / 2));
                            matrix.Translate(Width / 64, -Height / 4);
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(-1, -1, Width + 1, Height / 2));
                            waterPath.AddLine(0, Height / 4, Width, Height / 4);
                            switchPath.AddEllipse(new Rectangle(Width / 8, Height / 2 + Height / 8, 3 * Width / 4, Height / 8));
                            break;
                        case direction.down:
                            matrix.Translate(0, Height / 4);
                            matrix.RotateAt(-45, new Point(Width / 2, Height / 2 - Height / 4));
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(-1, Height / 2, Width + 1, Height / 2));
                            switchPath.AddEllipse(new Rectangle(Width / 8, Height / 4, 3 * Width / 4, Height / 8));
                            waterPath.AddLine(0, 3 * Height / 4, Width, 3 * Height / 4);
                            break;
                        case direction.left:
                            matrix.RotateAt(-45, new Point(Width / 2, Height / 2));
                            matrix.Translate(-Width / 4, Height / 16);
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(0, -1, Width / 2, Height + 1));
                            switchPath.AddEllipse(new Rectangle(5 * Width / 8, Height / 8, Width / 8, 3 * Height / 4));
                            waterPath.AddLine(Width / 4, 0, Width / 4, Height);
                            break;
                        case direction.right:
                            matrix.RotateAt(-45, new Point(Width / 2, Height / 2));
                            matrix.Translate(Width / 4, 0);
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(Width / 2, -1, Width / 2, Height + 1));
                            switchPath.AddEllipse(new Rectangle(2 * Width / 8, 1 * Height / 8, Width / 8, 6 * Height / 8));
                            waterPath.AddLine(3 * Width / 4, 0, 3 * Width / 4, Height);
                            break;

                    }
                    break;
                //双通道
                case ValveType.doubleChanel:
                    switch (Position)
                    {
                        case direction.up:
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(-1, Height/4, Width+1, Height / 2));
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(Width/4, 0, Width/2, Height / 4+1));
                            if(isON)
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,0),
                                new PointF(Width/2,Height/2),
                                new PointF(0,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(0, 3 * Height / 4, Width / 2, Height / 8));
                            }
                            else
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,0),
                                new PointF(Width/2,Height/2),
                                new PointF(Width,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(Width/2, 3 * Height / 4, Width / 2, Height / 8));
                            }
                            break;
                        case direction.down:
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(-1, Height / 4, Width + 1, Height / 2));
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(Width / 4, 3* Height/4-1, Width / 2, Height / 4+2));
                            if (isON)
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,Height),
                                new PointF(Width/2,Height/2),
                                new PointF(0,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(0,Height / 8, Width / 2, Height / 8));
                            }
                            else
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,Height),
                                new PointF(Width/2,Height/2),
                                new PointF(Width,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(Width/2, Height / 8, Width / 2, Height / 8));
                            }
                            break;
                        case direction.left:
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(Width/4, 0, Width/2, Height));
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(0, Height / 4, Width / 4+1, Height /2));
                            if (isON)
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,0),
                                new PointF(Width/2,Height/2),
                                new PointF(0,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(3*Width/4,0,Width/8,Height/2));
                            }
                            else
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,Height),
                                new PointF(Width/2,Height/2),
                                new PointF(0,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(3 * Width / 4, Width/2, Width / 8, Height / 2));
                            }
                            break;
                        case direction.right:
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(Width / 4, 0, Width / 2, Height));
                            g.FillRectangle(new SolidBrush(pipeColor), new Rectangle(3*Width/4-1, Height / 4, Width / 4 + 2, Height / 2));
                            if (isON)
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,Height),
                                new PointF(Width/2,Height/2),
                                new PointF(Width,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(Width / 8, Height / 2, Width / 8, Height / 2));
                            }
                            else
                            {
                                waterPath.AddLines(new PointF[]
                                {
                                new PointF(Width/2,0),
                                new PointF(Width/2,Height/2),
                                new PointF(Width,Height/2)
                                });
                                switchPath.AddEllipse(new Rectangle(Width/8,0,Width/8,Height/2));
                            }
                            break;

                    }
                    break;

            }
            #region 渐变色
            //渐变色
            Pen p;
            List<Color> listColor = new List<Color>();
            Function.GradientRamp(pipeColor, Color.White, Height / 4, ref listColor);
            for (int i = 0; i < listColor.Count; i++)
            {
                p = new Pen(new SolidBrush(listColor[i]), Height/4 - i);
                g.DrawPath(p, waterPath);
            }
            listColor.Clear();
            #endregion 渐变色

            #region 水流
            if (flowOK)
            {
                p = new Pen(Brushes.Green, 4);
                p.DashStyle = DashStyle.Dash;
                p.DashPattern = new float[] { 5, 5 };
                p.DashOffset = move;
                g.DrawPath(p, waterPath);
            }
            #endregion 水流

            if (isON)
            {
                g.FillPath(new SolidBrush(pipeColor), switchPath);
            }
            else
            {
                //关闭时开关位置
                if(valveType == ValveType.singleChanel)
                switchPath.Transform(matrix);
                g.FillPath(new SolidBrush(pipeColor), switchPath);
            }

        }

        private void UCValve_MouseEnter(object sender, EventArgs e)
        {
            BorderStyle = BorderStyle.FixedSingle;
            BackColor = Color.Transparent;
        }

        private void UCValve_MouseLeave(object sender, EventArgs e)
        {
            BorderStyle = BorderStyle.None;
            BackColor = Color.Transparent;
        }

        private void UCValve_MouseCaptureChanged(object sender, EventArgs e)
        {
            BackColor = Color.Transparent;
        }

        private void UCValve_MouseDown(object sender, MouseEventArgs e)
        {
            BackColor = Color.FromArgb(40, pipeColor.R, pipeColor.G, pipeColor.B);
        }
    }
}
